{
"#pragma parameter PHOSPHOR \"CRT - Phosphor ON/OFF\" 1.0 0.0 1.0 1.0\n"
"#pragma parameter InputGamma \"CRT - Input gamma\" 2.4 0.0 5.0 0.1\n"
"#pragma parameter OutputGamma \"CRT - Output Gamma\" 2.2 0.0 5.0 0.1\n"
"#pragma parameter SHARPNESS \"CRT - Sharpness Hack\" 1.0 1.0 5.0 1.0\n"
"#pragma parameter COLOR_BOOST \"CRT - Color Boost\" 1.5 1.0 2.0 0.05\n"
"#pragma parameter RED_BOOST \"CRT - Red Boost\" 1.0 1.0 2.0 0.01\n"
"#pragma parameter GREEN_BOOST \"CRT - Green Boost\" 1.0 1.0 2.0 0.01\n"
"#pragma parameter BLUE_BOOST \"CRT - Blue Boost\" 1.0 1.0 2.0 0.01\n"
"#pragma parameter SCANLINES_STRENGTH \"CRT - Scanline Strength\" 0.72 0.0 1.0 0.02\n"
"#pragma parameter BEAM_MIN_WIDTH \"CRT - Min Beam Width\" 0.86 0.0 1.0 0.02\n"
"#pragma parameter BEAM_MAX_WIDTH \"CRT - Max Beam Width\" 1.0 0.0 1.0 0.02\n"
"#pragma parameter CRT_ANTI_RINGING \"CRT - Anti-Ringing\" 0.8 0.0 1.0 0.1\n"
"#ifdef PARAMETER_UNIFORM\n"
"uniform float PHOSPHOR;\n"
"uniform float InputGamma;\n"
"uniform float OutputGamma;\n"
"uniform float SHARPNESS;\n"
"uniform float COLOR_BOOST;\n"
"uniform float RED_BOOST;\n"
"uniform float GREEN_BOOST;\n"
"uniform float BLUE_BOOST;\n"
"uniform float SCANLINES_STRENGTH;\n"
"uniform float BEAM_MIN_WIDTH;\n"
"uniform float BEAM_MAX_WIDTH;\n"
"uniform float CRT_ANTI_RINGING;\n"
"#else\n"
"#define PHOSPHOR 1.0\n"
"#define InputGamma 2.4\n"
"#define OutputGamma 2.2\n"
"#define SHARPNESS 2.0\n"
"#define COLOR_BOOST 1.5\n"
"#define RED_BOOST 1.0\n"
"#define GREEN_BOOST 1.0\n"
"#define BLUE_BOOST 1.0\n"
"#define SCANLINES_STRENGTH 0.72\n"
"#define BEAM_MIN_WIDTH 0.86\n"
"#define BEAM_MAX_WIDTH 1.0\n"
"#define CRT_ANTI_RINGING 1.0 \n"
"#endif\n"
"// END PARAMETERS //\n"
"\n"
"/* COMPATIBILITY\n"
"   - HLSL compilers\n"
"   - Cg   compilers\n"
"*/\n"
"\n"
"/*\n"
"   Hyllian's CRT Shader\n"
"  \n"
"   Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com\n"
"\n"
"   Permission is hereby granted, free of charge, to any person obtaining a copy\n"
"   of this software and associated documentation files (the \"Software\"), to deal\n"
"   in the Software without restriction, including without limitation the rights\n"
"   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n"
"   copies of the Software, and to permit persons to whom the Software is\n"
"   furnished to do so, subject to the following conditions:\n"
"\n"
"   The above copyright notice and this permission notice shall be included in\n"
"   all copies or substantial portions of the Software.\n"
"\n"
"   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n"
"   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n"
"   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n"
"   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n"
"   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n"
"   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n"
"   THE SOFTWARE.\n"
"\n"
"*/\n"
"\n"
"#define GAMMA_IN(color)     pow(color, float3(InputGamma, InputGamma, InputGamma))\n"
"#define GAMMA_OUT(color)    pow(color, float3(1.0 / OutputGamma, 1.0 / OutputGamma, 1.0 / OutputGamma))\n"
"\n"
"// Horizontal cubic filter.\n"
"\n"
"// Some known filters use these values:\n"
"\n"
"//    B = 0.0, C = 0.0  =>  Hermite cubic filter.\n"
"//    B = 1.0, C = 0.0  =>  Cubic B-Spline filter.\n"
"//    B = 0.0, C = 0.5  =>  Catmull-Rom Spline filter. This is the default used in this shader.\n"
"//    B = C = 1.0/3.0   =>  Mitchell-Netravali cubic filter.\n"
"//    B = 0.3782, C = 0.3109  =>  Robidoux filter.\n"
"//    B = 0.2620, C = 0.3690  =>  Robidoux Sharp filter.\n"
"//    B = 0.36, C = 0.28  =>  My best config for ringing elimination in pixel art (Hyllian).\n"
"\n"
"\n"
"// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif\n"
"\n"
"// Change these params to configure the horizontal filter.\n"
"const static float  B =  0.0; \n"
"const static float  C =  0.5;  \n"
"\n"
"const static float4x4 invX = float4x4(            (-B - 6.0*C)/6.0,         (3.0*B + 12.0*C)/6.0,     (-3.0*B - 6.0*C)/6.0,             B/6.0,\n"
"                                        (12.0 - 9.0*B - 6.0*C)/6.0, (-18.0 + 12.0*B + 6.0*C)/6.0,                      0.0, (6.0 - 2.0*B)/6.0,\n"
"                                       -(12.0 - 9.0*B - 6.0*C)/6.0, (18.0 - 15.0*B - 12.0*C)/6.0,      (3.0*B + 6.0*C)/6.0,             B/6.0,\n"
"                                                   (B + 6.0*C)/6.0,                           -C,                      0.0,               0.0);\n"
"\n"
"\n"
"struct input\n"
"{\n"
"    float2 video_size;\n"
"    float2 texture_size;\n"
"    float2 output_size;\n"
"    float  frame_count;\n"
"    float  frame_direction;\n"
"    float  frame_rotation;\n"
"};\n"
"\n"
"\n"
"struct out_vertex {\n"
"    float2 texCoord : TEXCOORD0;\n"
"};\n"
"\n"
"/*    VERTEX_SHADER    */\n"
"out_vertex main_vertex\n"
"(\n"
"    float4 position      : POSITION,\n"
"    out float4 oPosition : POSITION,\n"
"    float2 texCoord      : TEXCOORD0,\n"
"\n"
"    uniform float4x4 modelViewProj,\n"
"    uniform input IN\n"
")\n"
"{\n"
"    oPosition = mul(modelViewProj, position);\n"
"\n"
"    out_vertex OUT = {\n"
"        texCoord\n"
"    };\n"
"\n"
"    return OUT;\n"
"}\n"
"\n"
"\n"
"float4 main_fragment(in out_vertex VAR, uniform sampler2D s_p : TEXUNIT0, uniform input IN) : COLOR\n"
"{\n"
"    float2 TextureSize = float2(SHARPNESS*IN.texture_size.x, IN.texture_size.y);\n"
"\n"
"    float3 color;\n"
"    float2 dx = float2(1.0/TextureSize.x, 0.0);\n"
"    float2 dy = float2(0.0, 1.0/TextureSize.y);\n"
"    float2 pix_coord = VAR.texCoord*TextureSize+float2(-0.5,0.5);\n"
"\n"
"    float2 tc = (floor(pix_coord)+float2(0.5,0.5))/TextureSize;\n"
"\n"
"    float2 fp = frac(pix_coord);\n"
"\n"
"    float3 c00 = GAMMA_IN(tex2D(s_p, tc     - dx - dy).xyz);\n"
"    float3 c01 = GAMMA_IN(tex2D(s_p, tc          - dy).xyz);\n"
"    float3 c02 = GAMMA_IN(tex2D(s_p, tc     + dx - dy).xyz);\n"
"    float3 c03 = GAMMA_IN(tex2D(s_p, tc + 2.0*dx - dy).xyz);\n"
"    float3 c10 = GAMMA_IN(tex2D(s_p, tc     - dx).xyz);\n"
"    float3 c11 = GAMMA_IN(tex2D(s_p, tc         ).xyz);\n"
"    float3 c12 = GAMMA_IN(tex2D(s_p, tc     + dx).xyz);\n"
"    float3 c13 = GAMMA_IN(tex2D(s_p, tc + 2.0*dx).xyz);\n"
"\n"
"    //  Get min/max samples\n"
"    float3 min_sample = min(min(c01,c11), min(c02,c12));\n"
"    float3 max_sample = max(max(c01,c11), max(c02,c12));\n"
"\n"
"    float4x3 color_matrix0 = float4x3(c00, c01, c02, c03);\n"
"    float4x3 color_matrix1 = float4x3(c10, c11, c12, c13);\n"
"\n"
"    float4 invX_Px  = mul(invX, float4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0));\n"
"    float3 color0   = mul(invX_Px, color_matrix0);\n"
"    float3 color1   = mul(invX_Px, color_matrix1);\n"
"\n"
"    // Anti-ringing\n"
"    float3 aux = color0;\n"
"    color0 = clamp(color0, min_sample, max_sample);\n"
"    color0 = lerp(aux, color0, CRT_ANTI_RINGING);\n"
"    aux = color1;\n"
"    color1 = clamp(color1, min_sample, max_sample);\n"
"    color1 = lerp(aux, color1, CRT_ANTI_RINGING);\n"
"\n"
"    float pos0 = fp.y;\n"
"    float pos1 = 1 - fp.y;\n"
"\n"
"    float3 lum0 = lerp(float3(BEAM_MIN_WIDTH), float3(BEAM_MAX_WIDTH), color0);\n"
"    float3 lum1 = lerp(float3(BEAM_MIN_WIDTH), float3(BEAM_MAX_WIDTH), color1);\n"
"\n"
"    float3 d0 = clamp(pos0/(lum0+0.0000001), 0.0, 1.0);\n"
"    float3 d1 = clamp(pos1/(lum1+0.0000001), 0.0, 1.0);\n"
"\n"
"    d0 = exp(-10.0*SCANLINES_STRENGTH*d0*d0);\n"
"    d1 = exp(-10.0*SCANLINES_STRENGTH*d1*d1);\n"
"\n"
"    color = clamp(color0*d0+color1*d1, 0.0, 1.0);            \n"
"\n"
"    color *= COLOR_BOOST*float3(RED_BOOST, GREEN_BOOST, BLUE_BOOST);\n"
"\n"
"    float mod_factor = VAR.texCoord.x * IN.output_size.x * IN.texture_size.x / IN.video_size.x;\n"
"\n"
"    float3 dotMaskWeights = lerp(\n"
"                                 float3(1.0, 0.7, 1.0),\n"
"                                 float3(0.7, 1.0, 0.7),\n"
"                                 floor(fmod(mod_factor, 2.0))\n"
"                                  );\n"
"\n"
"    color.rgb *= lerp(1.0, dotMaskWeights, PHOSPHOR);\n"
"\n"
"    color  = GAMMA_OUT(color);\n"
"\n"
"    return float4(color, 1.0);\n"
"}\n"
"\n"
},
